from datetime import datetime
from datetime import timedelta
import math
import calendar


class DatetimeUtil:
    """
    日期时间工具类
    """

    _DT_FMT = '%Y-%m-%d %H:%M:%S'
    _DT_CLOSE_FMT = '%Y%m%d%H%M%S'
    _YEAR_FMT = '%Y'
    _YEAR_MONTH_FMT = '%Y%m'
    _DATE_FMT = '%Y-%m-%d'
    _DATE_CLOSE_FMT = '%Y%m%d'

    _ONE_DAY = 86400
    _ONE_HOUR = 3600
    _ONE_MINUTE = 60

    def __init__(self):
        pass

    @staticmethod
    def get_current_datetime(formate: str = _DT_FMT):
        return datetime.strftime(datetime.now(), formate)

    @staticmethod
    def get_current_date(formate: str = _DATE_FMT):
        return datetime.strftime(datetime.now(), formate)

    def datetime_to_str(self, dt: datetime):
        return dt.strftime(self._DT_FMT)

    def str_to_datetime(self, dt_str: str) -> datetime:
        try:
            return datetime.strptime(dt_str, self._DT_FMT)
        except ValueError as e:
            return None

    def to_date_str(self, dt: datetime):
        return dt.strftime(self._DATE_FMT)

    def to_close_datetime_str(self, dt: datetime):
        return dt.strftime(self._DT_CLOSE_FMT)

    def to_close_date_str(self, dt: datetime):
        return dt.strftime(self._DATE_CLOSE_FMT)

    def get_duration_str(self, from_dt: datetime, to_dt: datetime = datetime.now()):
        """
        获取日期时长，格式：天小时分
        :param from_dt:
        :param to_dt:
        :return:
        """

        if from_dt is None or to_dt is None:
            return '-'

        diff_secs = to_dt.timestamp() - from_dt.timestamp()

        day = diff_secs / self._ONE_DAY
        hour = (math.modf(day)[0] * self._ONE_DAY) / self._ONE_HOUR
        minute = (math.modf(hour)[0] * self._ONE_HOUR) / self._ONE_MINUTE

        if diff_secs > self._ONE_DAY:
            return "{}天{}时{}分".format(int(day), int(hour), int(minute))
        else:
            return "{}时{}分".format(int(hour), int(minute))

    def get_year(self, dt: datetime = datetime.now()):
        return dt.strftime(self._YEAR_FMT)

    def get_year_month(self, dt: datetime = datetime.now()):
        return dt.strftime(self._YEAR_MONTH_FMT)

    def get_month_last_day(self, dt: datetime) -> int:
        week_day, month_count_day = calendar.monthrange(dt.year, dt.month)
        return month_count_day

    def get_season_last_day(self, dt:datetime) -> tuple:
        month = dt.month
        if month in (1, 2, 3):
            return 3, 31

        if month in (4, 5, 6):
            return 6, 30

        if month in (7, 8, 9):
            return 9, 30

        return 12, 31


if __name__ == '__main__':
    o = DatetimeUtil()
    now = datetime.now()
    res = o.get_duration_str((now - timedelta(hours=0) - timedelta(minutes=36)), now)
    print(res)
